#ifndef COMMWITHBRIDGE_H
#define COMMWITHBRIDGE_H

#include "commSignal.h"
#include "mainwindow.h"
#include "jsonMsg.h"
#include "commWithBoard.h"
#include <QObject>
#include <QWidget>
#include <QKeyEvent>
#include <QTcpSocket>
#include <QUdpSocket>
#include <QtNetwork/QAbstractSocket>
#include <QString>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QTimer>
#include <QHash>
#include <QMutex>
#include <QMutexLocker>
#include <QDateTime>
#include <QList>

struct ArmInfo {
    bool arm_online;
    double arm_pose_left[7];
    double arm_joints_left[7];
    double arm_pose_right[7];
    double arm_joints_right[7];    
};

struct GripperInfo{
    bool online;
    double cur_pose_left;
    double cur_pose_right;
    bool cur_state_left;
    bool cur_state_right;
};

struct ChasisInfo {
    bool online;
    double speed[2];
    double pose[3];
    QString cur_task;
};

struct SysInfo {
    int error;
    int step;
    QString msg;
    int running_mode;
    int ctrl_mode;
};

struct RobotStatusInfo {
    ArmInfo arm_info;
    GripperInfo gripper_info;
    ChasisInfo chasis_info;
    bool vision_online;
    SysInfo sys_info;
};

class commWithBridge : public QObject
{
    Q_OBJECT
public:
    class MainWindow * mainWindow;
    commWithBoard * commWithBoard_;
    commWithBridge(MainWindow * mainWindow = nullptr, QObject *parent = nullptr);
    void commWithBridgeInit();
    ~commWithBridge();
    CommSignal * commRosToGuiSig;
    RobotStatusInfo robotStatusInfo;

    // 连接bridge服务器
    bool connToBridge(const QString &host = "127.0.0.1", quint16 tcpPort = 5002, quint16 udpPort = 5003);
    // 断开连接
    bool disconnFromBridge();
    // 发送消息
    bool sendMessage(QByteArray &message);
    // 检查连接状态
    bool isConnected() const;

    void sendAutoStartMsg();
    void sendAutoStopMsg();
    void sendAutoPauseMsg();
    void SendAutoToManualMsg();
    void SendManualToAutoMsg();

    void sendMoveForwardMsg();
    void sendMoveBackwardMsg();
    void sendMoveLeftMsg();
    void sendMoveRightMsg();
    void sendRobotEnMsg();
    void sendRobotDisMsg();

    void sendLeftGripperOpenMsg();
    void sendLeftGripperCloseMsg();
    void sendRightGripperOpenMsg();
    void sendRightGripperCloseMsg();

    void sendLeftArmXIMsg();
    void sendLeftArmXDMsg();
    void sendLeftArmYIMsg();
    void sendLeftArmYDMsg();
    void sendLeftArmZIMsg();
    void sendLeftArmZDMsg();
    void sendLeftArmRXIMsg();
    void sendLeftArmRXDMsg();
    void sendLeftArmRYIMsg();
    void sendLeftArmRYDMsg();
    void sendLeftArmRZIMsg();
    void sendLeftArmRZDMsg();

    void sendRightArmXIMsg();
    void sendRightArmXDMsg();
    void sendRightArmYIMsg();
    void sendRightArmYDMsg();
    void sendRightArmZIMsg();
    void sendRightArmZDMsg();
    void sendRightArmRXIMsg();
    void sendRightArmRXDMsg();
    void sendRightArmRYIMsg();
    void sendRightArmRYDMsg();
    void sendRightArmRZIMsg();
    void sendRightArmRZDMsg();

signals:
    // 连接状态变化
    void connStatusChanged(bool connected);
    // 错误发生
    void errOccurred(const QString &errStr);

public slots:
    void processGuiSig(int guiSig);
    void processBoardSig(int boardSig);
    
private slots:
    void handleConnected();
    void handleDisconnected();
    void handleTcpReadyRead();
    void handleUdpReadyRead();
    void handleErr(QAbstractSocket::SocketError socketErr);
    void handleTcpConnection();
    void handleTcpRecvTimeout();

    void processAutoSig(int guiSig);
    void processMoveSig(int guiSig);
    void processGripperSig(int guiSig);
    void processLeftArmSig(int guiSig);
    void processRightArmSig(int guiSig);
    void processTestSig(int guiSig);

private:
    QTcpSocket *tcpSocket;
    QTcpSocket *ioCtrlSocket;
    QUdpSocket *udpSocket;
    QTimer *tcpConnTimer;
    QTimer *tcpRecvTimer;
    
    QString host;
    quint16 tcpPort;

    QByteArray heartBeatByteArr;

    int curr_step;
    int curr_running_mode;
    int curr_ctrl_mode;

    void parseTcpJsonData(const QByteArray &jsonData);
    void parseUdpJsonData(const QByteArray &jsonData);
};

#endif // COMMWITHBRIDGE_H
